package org.summerframework.component.upload.util;


import org.summerframework.core.util.Base64Util;

import javax.activation.MimeType;
import java.io.*;
import java.security.MessageDigest;
import java.util.HashMap;

public class FileUtil {
    private static Long SIZE_500K = 512000L;

    private static Long SIZE_1M = 1048576L;

    private static MimeType mimeType = new MimeType();

    private static HashMap icons = null;

    public static String getFileLength(long length) {
        double f = (double) Math.round(((double) length / 1024D) * 100D) / 100D;
        return f + "k";
    }

    public static String getContentType(String name) {
        return mimeType.getParameter(name);
    }

    public static String getExtension(String name) {
        int i = name.lastIndexOf(46);
        if (i >= 0) {
            return name.substring(i + 1).toLowerCase();
        } else {
            return "";
        }
    }


    public boolean isText(String name) {
        String type = getContentType(name);
        return type.startsWith("text");
    }

    public boolean isDir(String name) {
        return (new File(name)).isDirectory();
    }

    public static void initIcons() {
        icons = new HashMap(16);
        icons.put("application", "binary");
        icons.put("text", "doc");
        icons.put("image", "image");
        icons.put("video", "movie");
        icons.put("audio", "sound");
    }

    public String getIcon(File file) {
        String contentType = getContentType(file.getName());
        contentType = contentType.substring(0, contentType.indexOf("/"));
        String icon = (String) icons.get(contentType);
        return icon + ".gif";
    }

    public static String trim(String str) {
        if (str == null) {
            return null;
        }
        str = str.trim();
        if (str.length() == 0) {
            return null;
        } else {
            return str;
        }
    }

    public static String getName(String path) {
        try {
            String fileName = getFileName(path);
            int i = fileName.lastIndexOf(46);
            if (i >= 0) {
                return fileName.substring(0, i);
            } else {
                return "";
            }
        } catch (Exception exception) {
            return "Unknown";
        }
    }

    public static String getFileName(String path) {
        try {
            char separatorChar = '/';
            int index = path.lastIndexOf(separatorChar);
            if (index < 0) {
                separatorChar = '\\';
                index = path.lastIndexOf(separatorChar);
            }
            return path.substring(index + 1);
        } catch (Exception exception) {
            return "Unknown";
        }
    }

    private static boolean isUnicodeFile(String path) throws Exception {
        FileInputStream fi = new FileInputStream(path);
        byte[] bom = new byte[20];
        int n = fi.read(bom);
        for (int i = 0; i < n; i++) {
            System.out.println(Integer.toHexString(bom[i]));
        }

        fi.close();
        if (bom[0] == 255 && bom[1] == 254) {
            return true;
        } else {
            System.err.println(new String(bom));
            return false;
        }
    }

    public static void delete(File dir) {
        if (dir.isDirectory()) {
            File[] files = dir.listFiles();
            if (files != null) {
                for (int i = 0; i < files.length; i++) {
                    delete(files[i]);
                }

            }
            dir.delete();
        } else {
            dir.delete();
        }
    }

    public static void copy(String src, String target) throws IOException {
        copy(new File(src), new File(target));
    }

    public static void copy(File file, File target) throws IOException {
        if (file.isDirectory()) {
            return;
        }

        if (!target.getParentFile().exists()) {
            target.getParentFile().mkdirs();
        }

        FileInputStream fi = null;
        FileOutputStream fo = null;
        try {
            fi = new FileInputStream(file);
            fo = new FileOutputStream(target);
            byte[] buff = new byte[1024];
            for (int n = 0; (n = fi.read(buff)) != -1; ) {
                fo.write(buff, 0, n);
            }

        } finally {
            if (fo != null) {
                fo.close();
            }
            if (fi != null) {
                fi.close();
            }
        }
    }

    /**
     * @param file
     * @param size
     * @return
     */
    public static boolean isBigFile(File file, Long size) {
        if (file.length() > size) {
            return true;
        }
        return false;
    }

    /**
     */
    public static boolean isFileType(String fileType, String[] allowType) {
        if (null == fileType || null == allowType) {
            return false;
        }
//		int a = 0;
        for (int i = 0; i < allowType.length; i++) {
            if (fileType.equals(allowType[i])) {
                return true;
            }
        }
        return false;
//		if(a!=0){

//		}
//		return true;
    }


    /**
     * 复制单个文件
     *
     * @param oldPath String 原文件路径 如：c:/fqf.txt
     * @param newPath String 复制后路径 如：f:/fqf.txt
     * @return boolean
     */
    public static void copyFile(String oldPath, String newPath) {
        try {
            int bytesum = 0;
            int byteread = 0;
            File oldfile = new File(oldPath);
            if (oldfile.exists()) { //文件存在时
                InputStream inStream = new FileInputStream(oldPath); //读入原文件
                FileOutputStream fs = new FileOutputStream(newPath);
                byte[] buffer = new byte[1444];
                int length;
                while ((byteread = inStream.read(buffer)) != -1) {
                    bytesum += byteread; //字节数 文件大小
                    System.out.println(bytesum);
                    fs.write(buffer, 0, byteread);
                }
                inStream.close();
            }
        } catch (Exception e) {
            System.out.println("复制单个文件操作出错");
            e.printStackTrace();

        }

    }

    /**
     * 复制整个文件夹内容
     *
     * @param oldPath String 原文件路径 如：c:/fqf
     * @param newPath String 复制后路径 如：f:/fqf/ff
     * @return boolean
     */
    public static void copyFolder(String oldPath, String newPath) {

        try {
            (new File(newPath)).mkdirs(); //如果文件夹不存在 则建立新文件夹
            File a = new File(oldPath);
            String[] file = a.list();
            File temp = null;
            for (int i = 0; i < file.length; i++) {
                if (oldPath.endsWith(File.separator)) {
                    temp = new File(oldPath + file[i]);
                } else {
                    temp = new File(oldPath + File.separator + file[i]);
                }

                if (temp.isFile()) {
                    FileInputStream input = new FileInputStream(temp);
                    FileOutputStream output = new FileOutputStream(newPath + "/" +
                            (temp.getName()).toString());
                    byte[] b = new byte[1024 * 5];
                    int len;
                    while ((len = input.read(b)) != -1) {
                        output.write(b, 0, len);
                    }
                    output.flush();
                    output.close();
                    input.close();
                }
                if (temp.isDirectory()) {//如果是子文件夹
                    copyFolder(oldPath + "/" + file[i], newPath + "/" + file[i]);
                }
            }
        } catch (Exception e) {
            System.out.println("复制整个文件夹内容操作出错");
            e.printStackTrace();

        }

    }

    /**
	 * 将文件转成base64 字符串
	 *
	 * @param file
	 * @return *
	 * @throws Exception
	 */
	@SuppressWarnings("restriction")
	public static String encodeBase64File(File file) throws Exception {
		FileInputStream inputFile = new FileInputStream(file);
		byte[] buffer = new byte[(int) file.length()];
		inputFile.read(buffer);
		inputFile.close();
		return Base64Util.encode(buffer);
	}

	/**
	 * 将base64字符解码保存文件
	 *
	 * @param base64Code
	 * @param file
	 * @throws Exception
	 */

	@SuppressWarnings("restriction")
	public static void decoderBase64File(String base64Code, File file) throws Exception {
		byte[] buffer = Base64Util.decodeAsByte(base64Code);
		FileOutputStream out = new FileOutputStream(file);
		out.write(buffer);
		out.close();
	}

	/**
     * 二进制流转Base64字符串
     *
     * @param data 二进制流
     * @return data
     * @throws IOException 异常
     */
    @SuppressWarnings("restriction")
	public static String byteToBase64(byte[] data) throws IOException {
        return data != null ? Base64Util.encode(data) : "";
    }


    /**
     * Base64字符串转 二进制流
     *
     * @param base64String Base64
     * @return base64String
     * @throws IOException 异常
     */
    @SuppressWarnings("restriction")
	public static byte[] base64ToByte(String base64String) throws IOException {
        return base64String != null ? Base64Util.decodeAsByte(base64String) : null;
    }

    /**
	 * 将文件转成base64 字符串
	 *
	 * @return *
	 * @throws Exception
	 */
	@SuppressWarnings("restriction")
	public static String streamToBase64(InputStream inputStream) throws Exception {
		byte[] buffer = new byte[inputStream.available()];
		inputStream.read(buffer);
		inputStream.close();
		return Base64Util.encode(buffer);
	}

	/**
	 * 将base64字符解码保存文件
	 *
	 * @param base64Code
	 * @throws Exception
	 */

	@SuppressWarnings("restriction")
	public static void base64ToStream(String base64Code, OutputStream outputStream) throws Exception {
		byte[] buffer = Base64Util.decodeAsByte(base64Code);
		outputStream.write(buffer);
		outputStream.close();
	}

	public static byte[] create(InputStream fis) throws Exception {
		byte[] buf = new byte[1024];
		MessageDigest com = MessageDigest.getInstance("MD5");
		int num;
		do {
			num = fis.read(buf);
			if (num > 0) {
				com.update(buf, 0, num);
			}
		} while (num != -1);

		//fis.close();
		return com.digest();
	}

	public static String getMD5(InputStream fis) throws Exception {
		byte[] b = create(fis);
		String result = "";
		for (int i = 0; i < b.length; i++) {
			result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
		}
		return result;
	}

}
